package com.jinxinol.core.util.encryption;

import java.security.MessageDigest;
import java.security.Provider;
import java.security.Security;
import java.util.HashSet;
import java.util.Set;

import com.jinxinol.core.util.StringUtils;

/**
 * <p>签名算法工具类。</p>
 * 
 */
public abstract class MessageDigestUtils {
	
	/**
	 * <p>内容的缺省编码方法。<p>
	 */
	private static final String DEFAULT_ENCODE = "UTF-8";
	
	private static final String DEFAULT_DIGEST_ALGORITHM = "MD5";
	
    /**
     * <p>获得指定服务的实现方法名称集合。</p>
     *
     * @param serviceType 服务类型。
     * @return String[] 实现方法名称集合。
     */
	public static String[] getCryptoImpls(String serviceType) {  
        Set<String> result = new HashSet<String>();  
        Provider[] providers = Security.getProviders();  
        for (int i=0; i<providers.length; i++) {  
        	Set<?> keys = providers[i].keySet();  
            for (Object keyObj : keys) {
            	String key = keyObj.toString();
                key =  key.split("   ")[0];  
                if (key.startsWith(serviceType+".")) {  
                	result.add(key.substring(serviceType.length()+1));  
                }
                else if (key.startsWith("Alg.Alias."+serviceType+".")) {  
                	result.add(key.substring(serviceType.length()+11));  
                }  
            }  
        }  
        return result.toArray(new String[result.size()]);  
    }
	
	/**
	 * <p>获得MessageDigest服务的实现方法名称集合。</p>
	 *
     * @return String[] 实现方法名称集合。
	 */
	public static String[] getMessageDigestImpls() {
		return getCryptoImpls("MessageDigest");
	}
    
	/**
	 * <p>生成消息签名。</p>
	 *
	 * @param algorithm 签名算法。
	 * @param content 内容字符串。
	 * @param encode　内容字符串的编码方法。
	 * @return byte[] 消息签名。
	 */
	public static byte[] digest(String algorithm, String content, String encode) {
        try {
            MessageDigest alga = MessageDigest.getInstance(algorithm);
            alga.update(content.getBytes(encode));
            return alga.digest();
        } catch (Exception e) {
        	return null;
        }
	}
	
	/**
	 * <p>生成消息签名。</p>
	 * <p>使用内容的缺省编码方法。</p>
	 *
	 * @param algorithm 签名算法。
	 * @param content 内容字符串。
	 * @return byte[] 消息签名。
	 */
	public static byte[] digest(String algorithm, String content) {
		return digest(algorithm, content, DEFAULT_ENCODE);
	}
	
	/**
	 * <p>生成消息签名，以十六进制的ASCII字符串形式返回。</p>
	 * <p>使用内容的缺省编码方法。</p>
	 *
	 * @param algorithm 签名算法。
	 * @param content 内容字符串。
	 * @param encode　内容字符串的编码方法。
	 * @return String 消息签名。
	 */
	public static String digestHEX(String algorithm, String content, String encode) {
		return StringUtils.bytesHEX(digest(algorithm, content, encode));
	}
	
	/**
	 * <p>生成消息签名，以十六进制的ASCII字符串形式返回。</p>
	 *
	 * @param algorithm 签名算法。
	 * @param content 内容字符串。
	 * @return String 消息签名。
	 */
	public static String digestHEX(String algorithm, String content) {
		return StringUtils.bytesHEX(digest(algorithm, content));
	}
	
	/**
	 * <p>生成消息签名，以十六进制的ASCII字符串形式返回。</p>
	 * <p>使用摘要的缺省算法。</p>
	 * @param content 内容字符串。
	 * @return String 消息签名。
	 */
	public static String digestHEX(String content){
		return StringUtils.bytesHEX(digest(DEFAULT_DIGEST_ALGORITHM, content));
	}
	
}
